package xyz.lwm.lazycat.beans;

import java.util.Stack;

/**
 * <h3>循环依赖检测</h3>
 * <pre>
 *     注入的循环依赖可以解决, 因为其本身对象已经构造完成.
 *     构造的循环依赖无法解决, 因为对象都没法创建, 会陷入无限循环, 栈溢出.
 *     所以构造循环必须检测出来, 并抛出异常.
 * </pre>
 *
 * @author lwm
 */
class InstantiableCircleUtil {

    // instantiable stack
    private static final Stack<Instantiable> stack = new Stack<>();

    public synchronized static void checkCircle(Instantiable instantiable) {
        int index = stack.indexOf(instantiable);
        if (index > -1) {
            int index2 = stack.indexOf(instantiable, index + 1);
            int end = index2 == -1 ? stack.size() : index2;
            StringBuilder circle = new StringBuilder();
            for (int i = index; i < end; i++) {
                circle.append(stack.get(i)).append(" -> ");
            }
            circle.append(instantiable);
            throw new BeansException("Circle dependency detected: " + circle);
        }
    }

    public static void push(Instantiable instantiable) {
        stack.push(instantiable);
    }

    public synchronized static void remove() {
        if (!stack.isEmpty()) {
            stack.pop();
        }
    }

}
